//      handwrite.c
//
//      Copyright 2017 hebinq@qq.com
//

#include <sys/stat.h>
#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-bindings.h>
#include <X11/extensions/XTest.h>
#include <X11/keysym.h>
#include <X11/extensions/XInput.h>
#include "shuxie.h"
#include <pthread.h>
#include <semaphore.h>

#include "handwrite.h"
#include "service.h"
#include "intext.h"
#include "iat_record.h"
#include "loginDialog.h"
#include "set_dialog.h"
#include "rw_config.h"


gboolean PASS_FLAG = FALSE;

typedef enum shuxie_type{
    KNN,
    DWT,
}XIETYPE;

XIETYPE xtype=KNN;



static gboolean
window_move_callback ( GtkWidget* widget, GdkEventButton *event, gpointer data )
{
    //fprintf(stderr,"move,%d\n",event->type);
    //ShuoXie* shuoxie=(ShuoXie*)data;
	if ( event->type == GDK_BUTTON_PRESS )
	{
        
		if (1 == event->button )//1 左　２　中　　３右/
		{
			gtk_window_begin_move_drag ( GTK_WINDOW ( gtk_widget_get_toplevel ( widget ) ),
			                             event->button,
			                             event->x_root,
			                             event->y_root,
			                             event->time );
		}	

	}
	

	return TRUE;
}

/*************************************************
 * 发送字符到输入法中
 * 
 * **********************************************/
static void
simulation_shuoxie_input ( int key_code )
{
	Display* disp = XOpenDisplay ( NULL );
	if ( disp == NULL )
		return;
	XTestFakeKeyEvent ( disp,key_code, True,0 );
	XTestFakeKeyEvent ( disp,key_code, False,0 );
	XFlush ( disp );
	XCloseDisplay ( disp );
}

static void
set_font_size ( GtkWidget *bt )
{
	GtkWidget *font_label;
	PangoFontDescription* text_font = NULL;
	//~ text_font = pango_font_description_from_string("Arial,bold 13");
	text_font = pango_font_description_from_string ( "WenQuanYi Zen Hei 10" );
	font_label = gtk_bin_get_child ( GTK_BIN ( bt ) );
	gtk_widget_modify_font ( font_label, text_font );
}



static void
stroke_clean_draw ( ShuoXie *shuoxie )
{
	stroke_clean ( shuoxie->stk );
	gtk_widget_queue_draw ( shuoxie->window );//刷图区域
}

static gboolean
create_dbus ( ShuoXie *shuoxie )
{
	GError* error = NULL;
	guint   result;    
    
	shuoxie->bus = dbus_g_bus_get ( DBUS_BUS_SESSION, &error );
	if ( !shuoxie->bus )
	{
		g_warning ( "Failed to connect to the D-BUS daemon: %s", error->message );
		return FALSE;
	}
	shuoxie->proxy = dbus_g_proxy_new_for_name ( shuoxie->bus,
	                  DBUS_SERVICE_DBUS,
	                  DBUS_PATH_DBUS,
	                  DBUS_INTERFACE_DBUS );
	org_freedesktop_DBus_request_name ( shuoxie->proxy,
	                                    DBUS_SHUOXIE_SERVICE,
	                                    DBUS_NAME_FLAG_DO_NOT_QUEUE, &result, &error );

    

	ShuoXieService *service = g_object_new ( TYPE_SHUOXIE_SERVICE, NULL );//创建一个类对象 
	dbus_g_connection_register_g_object ( shuoxie->bus, DBUS_SHUOXIE_SERVICE_PATH, G_OBJECT ( service ) );
	shuoxie->service = service;
    if(!shuoxie->service)
    {
        g_warning("fcitx-shuoxie.create_dbus:%s\n",error->message);
        return FALSE;
    }
	return TRUE;
}
/**************************************************
 * 发送文本 事件
 * 
 * *************************************************/
static void
send_word_callback ( GtkButton *button, gpointer data )
{
	ShuoXie *shuoxie = ( ShuoXie * ) data;
	const gchar *label;
    
	label = gtk_button_get_label ( GTK_BUTTON ( button ) );
	dbg ( "%s \n", label );
    
	if ( !label )
		return ;
    
    //printf("添加:%s,%d\n",label,shuxie_character_strokeCount(shuoxie->stk->newcharactera));
    if(shuoxie->autoaddword>0){//autoaddword=true
        if(shuoxie->pagenum>0){//当前页的字不记录
    if(shuxie_character_strokeCount(shuoxie->stk->newcharactera)>0){    
        //printf("加入新字模 %s\n",label);
        gchar instr[16];
        sprintf(instr,"%s",label);
        shuxie_character_setword(shuoxie->stk->newcharactera,instr);
        shuxie_recognizer_addUserCharacter(shuoxie->stk->recognizer,shuoxie->stk->newcharactera);
        
        }
        }
    }
    shuxie_character_clear(shuoxie->stk->newcharactera);
	shuoxie_serice_sendword ( shuoxie->service, label );

	stroke_clean_draw ( shuoxie );
    
}

static void
shuoxie_english_callback ( GtkButton *button, gpointer data )
{
	ShuoXie *shuoxie = ( ShuoXie * ) data;
	int i;
	gchar *english_info[HAND_WORD_NUM] = {"a","b","c","d","e","f","g","h","i",
	                                      "j","k","l","m","n","o","p","q","r",
	                                      "s","t","u","v","w","x","y","z","A",
	                                      "B","C","D","E","F","G","H","I","J",
	                                      "K","L","M","N","O","P","Q","R","S",
	                                      "T","U","V","W","X","Y","Z","'","\""
	                                     };

	for ( i = 0; i < HAND_WORD_NUM; i++ )
	{
        
		shuoxie->value[i] = english_info[i];
		if ( i < HAND_BUTTON_NUM )
		{
			gtk_button_set_label ( GTK_BUTTON ( shuoxie->hand_button[i] ), english_info[i] );
			set_font_size ( shuoxie->hand_button[i] );
            
		}
	}
	shuoxie->pagenum = 0;
	stroke_clean_draw ( shuoxie );
}

static void
shuoxie_number_callback ( GtkButton *button, gpointer data )
{
	ShuoXie *shuoxie = ( ShuoXie * ) data;
	int i;
	gchar *number_info[HAND_WORD_NUM] = {"1","2","3","4","5","6","7","8","9","0",".","-",
                                         "+","*","/","=","(",")",",","?","!",":","\"","'",	                                     
	                                     "{","}","<",">","[","]","%","#","@","$","^","&",	                                     
	                                     "_","\\","`","~","0","9","8","7","6",
	                                     "5","4","3","2","1","0","10","100","500"
	                                    };

	for ( i = 0; i < HAND_WORD_NUM; i++ )
	{
		shuoxie->value[i] = number_info[i];
		if ( i < HAND_BUTTON_NUM )
		{
			gtk_button_set_label ( GTK_BUTTON ( shuoxie->hand_button[i] ), number_info[i] );//改变按钮构件的文本 
			set_font_size ( shuoxie->hand_button[i] );
		}
	}
	shuoxie->pagenum = 0;
	stroke_clean_draw ( shuoxie );
}

static void
shuoxie_prevpage_callback ( GtkButton *button, gpointer data )
{
	ShuoXie *shuoxie = ( ShuoXie * ) data;
	int i, j;

	if ( shuoxie->pagenum == 0 )
		return;
	shuoxie->pagenum--;
	j = HAND_BUTTON_NUM * shuoxie->pagenum;
	for ( i = 0; i < HAND_BUTTON_NUM; i++ )
	{
		gtk_button_set_label ( GTK_BUTTON ( shuoxie->hand_button[i] ), shuoxie->value[j] );
		set_font_size ( shuoxie->hand_button[i] );
        
		j++;
	}

}

static void
shuoxie_nextpage_callback ( GtkButton *button, gpointer data )
{
	ShuoXie *shuoxie = ( ShuoXie * ) data;
	int i, j;

	if ( shuoxie->pagenum >= ( HAND_WORD_NUM / HAND_BUTTON_NUM )-1 )
		return;
	shuoxie->pagenum++;
	j = HAND_BUTTON_NUM * shuoxie->pagenum;
	for ( i = 0; i < HAND_BUTTON_NUM; i++ )
	{
		gtk_button_set_label ( GTK_BUTTON ( shuoxie->hand_button[i] ), shuoxie->value[j] );
		set_font_size ( shuoxie->hand_button[i] );
		j++;
	}

}

static void
shuoxie_backspace_callback ( GtkButton *button, gpointer data )
{
	simulation_shuoxie_input ( 22 );  /* 输入backspace键 */
}

static void
shuoxie_spaces_callback ( GtkButton *button, gpointer data )
{
	simulation_shuoxie_input ( 65 );		/* 输入空格键 */
}

static void
shuoxie_close_callback ( GtkButton *button, gpointer data )
{
	ShuoXie *shuoxie = ( ShuoXie * ) data;
    
    
    gchar modefilepath[256];

#if 0
	gtk_widget_hide ( shuoxie->window );
#else
	
	//保存字库
	
    sprintf(modefilepath,"%s/handwrite.model",getUserModelDir());
    shuxie_recognizer_saveModel(shuoxie->stk->recognizer,modefilepath);
    //保存配置
    set_autoaddword(shuoxie->autoaddword);
    set_bjcolor(&shuoxie->bj_color);
    set_hbcolor(&shuoxie->hb_color);

    
    iat_logout();

	//消毁对象
    shuxie_character_destroy(shuoxie->stk->newcharactera);
   shuxie_character_destroy(shuoxie->stk->charactera);   
   shuxie_recognizer_destroy(shuoxie->stk->recognizer);
   
    cairo_surface_destroy (shuoxie->stk->surface);  
	gtk_main_quit ();
#endif
    
}

static void
shuoxie_enter_callback ( GtkButton *button, gpointer data )
{
	simulation_shuoxie_input ( 36 );		/* 输入空格键 */
}
/***************************************
* 从字库中取字
***************************************/
static void
get_word_from_charlib ( ShuoXie *shuoxie )
{
	
    shuxie_resultword_t *result;
	size_t i;
	const char *value;


    if(xtype==KNN)
	result=shuxie_toword_knn(shuoxie->stk->recognizer,shuoxie->stk->charactera,HAND_WORD_NUM);
    else
        result=shuxie_toword_dwt(shuoxie->stk->recognizer,shuoxie->stk->charactera,HAND_WORD_NUM);
    if ( result == NULL )
	{
		
        fprintf ( stderr, "%s\n", "识别出错！" );
		return;
	}


	for(i=0;i<shuxie_resultword_count(result);++i)
	{
		
        value=shuxie_resultword_at(result,i);
		shuoxie->value[i] = ( gchar * ) value;
		if ( i < HAND_BUTTON_NUM )
		{
			gtk_button_set_label ( GTK_BUTTON ( shuoxie->hand_button[i] ), value );
			set_font_size ( shuoxie->hand_button[i] );
		}
	}
	shuoxie->pagenum = 0;

	
    shuxie_resultword_destroy(result);
}
/* 将 surface 初始化为白色*/  
static void clear_surface (cairo_surface_t *surface,GdkColor *bjcolor)  
{  
    cairo_t *cr;  
    gchar filepath[256];
    sprintf ( filepath, "%s/writer.png",  getThemeDir());
    cr = cairo_create (surface);  
    // 画背景图  
    // 获取图片  
    GdkPixbuf *src_pixbuf = gdk_pixbuf_new_from_file(filepath, NULL);   
    if(!src_pixbuf)
    {
       cairo_set_source_rgb (cr, bjcolor->red/255, bjcolor->green/255, bjcolor->blue/255);
        cairo_paint (cr); 
    }
    else{
    // 指定图片大小  
    GdkPixbuf* dst_pixbuf = gdk_pixbuf_scale_simple(src_pixbuf, 
                                                    gdk_pixbuf_get_width(src_pixbuf),
                                                    gdk_pixbuf_get_height(src_pixbuf), GDK_INTERP_BILINEAR);  
    // dst_pixbuf作为cr环境的画图原材料，(0, 0)：画图的起点坐标  
    gdk_cairo_set_source_pixbuf(cr, dst_pixbuf, 0, 0);  
    cairo_paint(cr);    // 绘图  
    g_object_unref(dst_pixbuf);  
    g_object_unref(src_pixbuf);
    }
    
    cairo_destroy (cr);  

} 
/* 创造一个新的、大小适当的 surface 去存储我们的涂鸦 */  
static gboolean configure_event_cb (GtkWidget  *widget,  
                    GdkEventConfigure *event,  
                    gpointer           data)  
{  
    ShuoXie *shuoxie = ( ShuoXie * ) data;
    if (shuoxie->stk->surface)  
        cairo_surface_destroy (shuoxie->stk->surface);  
  
    shuoxie->stk->surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget),  
              CAIRO_CONTENT_COLOR,  
              gtk_widget_get_allocated_width (widget),  
              gtk_widget_get_allocated_height (widget));  
  
    /* 将 surface 初始化为白色*/  
    clear_surface (shuoxie->stk->surface,&(shuoxie->bj_color));  
    
    /* 我们做了处理后，不必再做进一步的处理 */  
    return TRUE;  
} 

 /*通过 surface 重绘屏幕。 
 * 接收一个现有的 cairo_t 对象，绘制widget的暴露部分。 
 */  
static gboolean draw_cb (GtkWidget *widget,  
         cairo_t   *cr,  
         gpointer   data)  
{  
    ShuoXie *shuoxie = ( ShuoXie * ) data;
    cairo_set_source_surface (cr, shuoxie->stk->surface, 0, 0);  
    cairo_paint (cr);  
    return FALSE;  
} 
/*在指定的位置绘制一个矩形 */  
static void draw_brush (GtkWidget *widget,  cairo_surface_t *surface,Point last,Point p,GdkColor *hbcolor)  
{  
    cairo_t *cr;  
  
    /* Paint to the surface, where we store our state */  
    cr = cairo_create (surface);  
    cairo_set_source_rgb(cr,hbcolor->red/255,hbcolor->green/255,hbcolor->blue/255);
  	if(last.x == -1 && last.y == -1) {
		cairo_move_to (cr, p.x, p.y);		
		cairo_line_to (cr, p.x+1, p.y+1);	

	}
	else{ 


	cairo_move_to (cr, last.x, last.y);
	cairo_line_to (cr, p.x, p.y);
	
	}
    //cairo_rectangle (cr, x - 3, y - 3, 6, 6);  
    //cairo_fill (cr);  
  cairo_set_line_width (cr, 3.0);
	cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
	cairo_stroke  (cr);
    cairo_destroy (cr);  
    /* Now invalidate the affected region of the drawing area. */  
    //gtk_widget_queue_draw_area (widget, x - 3, y - 3, 6, 6);  
    gtk_widget_queue_draw ( widget );
}  

static gboolean
handwriter_press_filter ( GtkWidget *widget, GdkEventButton *event, gpointer data )
{
	ShuoXie *shuoxie = ( ShuoXie * ) data;
	Point p;
    if (shuoxie->stk->surface == NULL)  
        return FALSE;  
  
    if (event->button == GDK_BUTTON_PRIMARY)  
    {  
    	if ( shuoxie->stk->timer > 0 ){	            
			g_source_remove ( shuoxie->stk->timer );//时间清0
        }
		stroke_start ( shuoxie->stk );

		PASS_FLAG = TRUE;

    	p.x=(short)event->x;
    	p.y=(short)event->y;

        draw_brush (widget,shuoxie->stk->surface,shuoxie->stk->last,p,&shuoxie->hb_color);  
    }  
    
	return FALSE;
}

static gboolean
handwriter_timeout ( gpointer data )
{
	ShuoXie *shuoxie = ( ShuoXie * ) data;

	

	stroke_stop ( shuoxie->stk );

	get_word_from_charlib ( shuoxie );		/* 从字库中获取字 */
	stroke_clean ( shuoxie->stk );
    clear_surface (shuoxie->stk->surface,&(shuoxie->bj_color));  
    //gtk_widget_queue_draw (widget);
	//~ gtk_widget_queue_draw (shuoxie->window);

	shuoxie->stk->num = 0;
	
    shuxie_character_clear(shuoxie->stk->charactera);
    if(shuoxie->autoaddword==0){//autoaddword=true       
        shuxie_character_clear(shuoxie->stk->newcharactera);
    }
	return FALSE;
}

static gboolean
handwriter_release_filter ( GtkWidget *widget, GdkEventButton *event, gpointer data )
{
	ShuoXie *shuoxie = ( ShuoXie * ) data;
	Point p;

	if ( 1 == event->button )
	{
		p.x = -1;
		p.y = -1;
		add_point_start ( shuoxie->stk,p );

		PASS_FLAG = FALSE;
		
		gtk_widget_queue_draw ( widget );//指定刷图区域
		shuoxie->stk->num = shuoxie->stk->num + 1;
		shuoxie->stk->timer = g_timeout_add ( 1000, handwriter_timeout, shuoxie );//添加一个Timeout函数
	}
	return FALSE;
}
/**********************************************
* 按钮移动 事件处理
***********************************************/
static gboolean handwriter_motion_filter ( GtkWidget *widget, GdkEventMotion *event, gpointer data )
{
	ShuoXie *shuoxie = ( ShuoXie * ) data;
	GdkModifierType state;
	Point p;
	int x,y;
	
    if (shuoxie->stk->surface == NULL)  
        return FALSE;  
  \
  	if(PASS_FLAG)
        {
            
        	gdk_window_get_pointer ( event->window, &x, &y, &state );//获取point
        	shuxie_character_addPoint(shuoxie->stk->charactera,shuoxie->stk->num,x,y);
       		shuxie_character_addPoint(shuoxie->stk->newcharactera,shuoxie->stk->num,x,y);
        }
        else
        	return FALSE;

        //printf("state:%d,%d;%d,%d\n",state,event->state,x,event->x_root);
        
    if (event->state & GDK_BUTTON1_MASK){  
    	p.x = ( short ) x;
		p.y = ( short ) y;
		
        draw_brush (widget,shuoxie->stk->surface,shuoxie->stk->last,p,&shuoxie->hb_color);     
        stroke_store ( shuoxie->stk, p );  
    }
    
	return FALSE;
}

static gboolean
handwriter_notify_event ( GtkWidget * widget, GdkEventExpose * event, gpointer data )
{
	GdkCursorType ct;
	
	ct = GDK_PENCIL;
	gdk_window_set_cursor ( gtk_widget_get_window (widget) , gdk_cursor_new ( ct ) );
	return FALSE;
}

static GtkWidget *
create_handwriter_canvas ( ShuoXie *shuoxie,int w,int h )
{
	
	GtkWidget *ebox;
	ebox =gtk_drawing_area_new ();  // gtk_event_box_new();//将响应事件的构件加入到事件盒构件
	gtk_widget_set_size_request (ebox, w, h);  
	//// 捕获事件
	gtk_widget_set_events ( ebox, gtk_widget_get_events ( ebox )
	                        | GDK_LEAVE_NOTIFY_MASK
	                        | GDK_BUTTON_PRESS_MASK
	                        | GDK_BUTTON_RELEASE_MASK
	                        | GDK_POINTER_MOTION_MASK
	                        | GDK_POINTER_MOTION_HINT_MASK
				| GDK_ENTER_NOTIFY_MASK
				| GDK_LEAVE_NOTIFY_MASK );

	
	shuoxie->stk = stroke_create ( w,h );		/* 手写初始化 */
    
	
    
	//按下事件
	g_signal_connect ( ebox, "button_press_event",
	                   G_CALLBACK ( handwriter_press_filter ), shuoxie );
	//放开事件
	g_signal_connect ( ebox, "button_release_event",
	                   G_CALLBACK ( handwriter_release_filter ), shuoxie );
	//移动事件
	g_signal_connect ( ebox, "motion_notify_event",
	                   G_CALLBACK ( handwriter_motion_filter ), shuoxie );
	
    
	//鼠标指针进入组件
	g_signal_connect ( ebox, "enter-notify-event",
	                   G_CALLBACK ( handwriter_notify_event ), NULL );
    /* Signals used to handle the backing surface 曝光 */  
    g_signal_connect (ebox, "draw",  
                      G_CALLBACK (draw_cb), shuoxie);  
    g_signal_connect (ebox,"configure-event",  
                      G_CALLBACK (configure_event_cb), shuoxie);
	return ebox;
}


static void
check_button_callback ( GtkWidget *check_button, gpointer data )
{
    ShuoXie *shuoxie = ( ShuoXie * ) data;  
   
    if(gtk_toggle_button_get_active(check_button))
        {  
    //printf("check button selected\n"); 
            shuoxie->autoaddword++;
    }  
    else  
    {  
    //printf("check button unselected\n");  
        shuoxie->autoaddword=0;
    }  
    
}
static void
check_bottom_callback ( GtkWidget *check_button, gpointer data )
{
    ShuoXie *shuoxie = ( ShuoXie * ) data;
    GdkScreen *gdk_screen;
    gint screen_width, screen_height;
    int x,y;
    int w,h;
    gdk_screen = gdk_screen_get_default();

        screen_width = gdk_screen_get_width(gdk_screen);
        screen_height= gdk_screen_get_height(gdk_screen);

         gtk_window_get_position(GTK_WINDOW(shuoxie->window),&x,&y);
         gtk_window_get_size(GTK_WINDOW(shuoxie->window),&w,&h);  

         gtk_window_move(GTK_WINDOW(shuoxie->window), x , screen_height-h);// 移动窗体
    
    
}
static void
intext_callback ( GtkButton *button, gpointer data )
{
    ShuoXie *shuoxie = ( ShuoXie * ) data;
    
    
    char instring[17];
    if(shuoxie->autoaddword>0){
    if(shuxie_character_strokeCount(shuoxie->stk->newcharactera)>0)
    if(instr_callback(instring)==GTK_RESPONSE_OK)
    {        
        g_print("%s\n",instring);
        if (strlen( instring)<1 )
            return ;
   
        if(shuxie_character_strokeCount(shuoxie->stk->newcharactera)>0){        
        shuxie_character_setword(shuoxie->stk->newcharactera,instring);
        shuxie_recognizer_addUserCharacter(shuoxie->stk->recognizer,shuoxie->stk->newcharactera);
        
        }
    }
    }
    shuxie_character_clear(shuoxie->stk->newcharactera);
}
static void
set_callback ( GtkButton *button, gpointer data )
{
    //printf("abc");
    ShuoXie *shuoxie = ( ShuoXie * ) data;
    
    
    shuoxie->xfup=upload_on;
    if(set_dialog(shuoxie)==GTK_RESPONSE_OK){
        upload_on=shuoxie->xfup;
        gtk_window_set_opacity(GTK_WINDOW(shuoxie->window), shuoxie->opacity); // 设置透明度函数  
        gtk_widget_queue_draw ( shuoxie->hand_fixed );        
    }
        
    
}
static void
about_callback(GtkButton *button,gpointer data)
{

	ShuoXie *shuoxie=(ShuoXie*)data;
	GtkWidget* aboutDialog;
	GdkPixbuf *logo;
	GError *error=NULL;
	char uifile[256];
    sprintf(uifile,"%s/default.glade",getThemeDir());
	GtkBuilder *builder=gtk_builder_new(); 
	if(!gtk_builder_add_from_file(builder, uifile, NULL)){  
                printf("cannot load UI file!\n");              
            }
	//aboutDialog=gtk_about_dialog_new();
	aboutDialog = GTK_WIDGET(gtk_builder_get_object (builder, "about_dialog"));  
   
	char logofile[256];
    sprintf(logofile,"%s/shuoxie-logo.png",getThemeDir());
	logo=gdk_pixbuf_new_from_file(logofile,&error);
    if(!error)
        gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(aboutDialog),logo);
    else
    {
        g_print("Error:%s\n",error->message);
        g_error_free(error);
    }
   

    gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(aboutDialog), "2.0");

    gtk_about_dialog_set_comments(

          GTK_ABOUT_DIALOG(aboutDialog), "说和写识别小工具");

    gtk_about_dialog_set_copyright(

          GTK_ABOUT_DIALOG(aboutDialog),"(C) 2017 caterpillar \n语音技术由科大讯飞提供\thttp://www.xfyun.cn/");


    gtk_about_dialog_set_license(
          GTK_ABOUT_DIALOG(aboutDialog), "GPL v2");

    gtk_about_dialog_set_website(
          GTK_ABOUT_DIALOG(aboutDialog), "http://www.xfyun.cn/");


    gtk_dialog_run(GTK_DIALOG(aboutDialog));

    gtk_widget_destroy(aboutDialog);
    
    g_object_unref(G_OBJECT(builder)); 
	//gtk_widget_show(aboutDialog);	
	
}
/**********************************************
 *
 *
 *********************************************/
static void
iat_callback ( GtkWidget *widget, gpointer data )
{
    /*
  
    pthread_t id;
    int ret;  
    
    ret=pthread_create(&id,NULL,(void *) iat_pthread,(GtkButton*)widget);
    if(ret!=0){
    printf ("Create pthread error!\n");
    return ;
    }    */
    static int iat_err;
    if(gtk_toggle_button_get_active(widget))
    {  
        set_iat_ui(widget);
        iat_err=iat_start();    
    }  
    else  
    {  
        if(!iat_err){
            iat_end();
            set_iat_ui(NULL);
        }
    }  
}
/*
static gint
my_popup_handler (GtkWidget *widget, GdkEvent *event)
{
   GtkMenu *menu;
   GdkEventButton *event_button;

   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_MENU (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
	
	

   menu = GTK_MENU (widget);
	

   if (event->type == GDK_BUTTON_PRESS)
   {
      event_button = (GdkEventButton *) event;
      if (event_button->button == 1)
      {
          gtk_widget_show_all(GTK_WIDGET(menu));
         gtk_menu_popup (menu, NULL, NULL, NULL, NULL,
         event_button->button, event_button->time);
         return TRUE;
      }
   }
  
   return FALSE;
}
*/


//读取图像
static GtkWidget* get_button_image(char* filename,int w,int h)
{
    const GdkPixbuf *src_pixbuf;
   GdkPixbuf *dest_pixbuf;
   //读取图片参数
   src_pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
   //将src_pixbuf设置成屏幕大小
   dest_pixbuf = gdk_pixbuf_scale_simple(src_pixbuf, w, h, GDK_INTERP_HYPER);
       //从dest_pixbuf中读取图片存于image中
   GtkWidget *img_space=gtk_image_new_from_pixbuf(dest_pixbuf);
   GtkWidget *button =gtk_button_new();//gtk_button_new_from_icon_name ("shuoxie-pacebar-symbolic", GTK_ICON_SIZE_BUTTON);
   gtk_button_set_image(button,img_space);
   return button;
}

//系统按钮 TOP
static void
create_headbar( GtkWidget *header_bar,GtkBuilder *builder,ShuoXie *shuoxie)
{

   //GtkWidget *start_separator=gtk_separator_tool_item_new();
    //gtk_action_bar_pack_start(GTK_CONTAINER(header_bar),start_separator);
  //讯飞
    GtkWidget *xf_bt;
    char tmpstr[256];
    sprintf(tmpstr,"%s/mic.png",getThemeDir());
    const GdkPixbuf *src_pixbuf;
   GdkPixbuf *dest_pixbuf;
   //读取图片参数
  src_pixbuf = gdk_pixbuf_new_from_file(tmpstr, NULL);
   //将src_pixbuf设置成屏幕大小
   dest_pixbuf = gdk_pixbuf_scale_simple(src_pixbuf, 24, 24, GDK_INTERP_HYPER);
       //从dest_pixbuf中读取图片存于image
   GtkWidget *img_mic=gtk_image_new_from_pixbuf(dest_pixbuf);
    xf_bt=gtk_toggle_button_new();
    gtk_button_set_image(xf_bt,img_mic);
    gtk_action_bar_pack_start(GTK_CONTAINER(header_bar),xf_bt);
    gtk_toggle_button_set_active(xf_bt,FALSE);
    g_signal_connect ( xf_bt, "clicked", G_CALLBACK ( iat_callback ), shuoxie );

    //删除
   GtkWidget *backspace_button = gtk_button_new_from_icon_name ("edit-clear-symbolic",
                                                      GTK_ICON_SIZE_BUTTON);
  gtk_action_bar_pack_start ( GTK_CONTAINER (header_bar),backspace_button);
   g_signal_connect (backspace_button, "clicked", G_CALLBACK ( shuoxie_backspace_callback ), NULL );
   //空格

   sprintf(tmpstr,"%s/spacebar.png",getThemeDir());
   GtkWidget *space_button =get_button_image(tmpstr,24,24);
  gtk_action_bar_pack_start ( GTK_CONTAINER (header_bar),space_button);
   g_signal_connect ( space_button, "clicked", G_CALLBACK ( shuoxie_spaces_callback ), NULL );
   //回车
   sprintf(tmpstr,"%s/enter.png",getThemeDir());
   GtkWidget *enter_button = get_button_image(tmpstr,24,24);
  gtk_action_bar_pack_start ( GTK_CONTAINER (header_bar),enter_button);
   g_signal_connect ( enter_button, "clicked", G_CALLBACK ( shuoxie_enter_callback ), NULL );

    //关闭
    GtkWidget *close_bt;
    close_bt=gtk_button_new_from_icon_name ("window-close-symbolic",
                                                        GTK_ICON_SIZE_BUTTON);
    gtk_action_bar_pack_end(header_bar,close_bt);
    g_signal_connect(close_bt,"clicked",G_CALLBACK(shuoxie_close_callback),shuoxie);	
     
    GtkWidget *end_separator=gtk_separator_tool_item_new();
    gtk_action_bar_pack_end(GTK_CONTAINER(header_bar),end_separator);

    //关于
    GtkWidget *about_bt;
    //about_bt=GTK_WIDGET(gtk_builder_get_object(builder,"bt_about"));
    about_bt=gtk_button_new_from_icon_name ("go-home-symbolic",
                                                        GTK_ICON_SIZE_BUTTON);
    gtk_action_bar_pack_end(GTK_CONTAINER(header_bar),about_bt);
    g_signal_connect(about_bt,"clicked",G_CALLBACK(about_callback),shuoxie);



    //gtk_header_bar_set_show_close_button(header_bar,FALSE);
    

}
 //功能按钮    BOTTOM
static void 
create_handbt_bar(GtkWidget *hand_bts,GtkBuilder *builder,ShuoXie *shuoxie)
{

    GtkWidget *previous_button = gtk_button_new_from_icon_name ("go-previous-symbolic",
                                                            GTK_ICON_SIZE_BUTTON);
    gtk_action_bar_pack_start ( GTK_CONTAINER (hand_bts), previous_button);
    g_signal_connect ( previous_button, "clicked", G_CALLBACK (shuoxie_prevpage_callback  ), shuoxie );  
    
    GtkWidget *next_button = gtk_button_new_from_icon_name ("go-next-symbolic",
                                                        GTK_ICON_SIZE_BUTTON);
    gtk_action_bar_pack_start ( GTK_CONTAINER (hand_bts),next_button);     
     g_signal_connect ( next_button, "clicked", G_CALLBACK (shuoxie_nextpage_callback  ), shuoxie );   


     GtkWidget *abc_button = gtk_button_new_from_icon_name ("format-text-bold-symbolic",
                                                        GTK_ICON_SIZE_BUTTON);
    gtk_action_bar_pack_start ( GTK_CONTAINER (hand_bts),abc_button);     
     g_signal_connect ( abc_button, "clicked", G_CALLBACK (shuoxie_english_callback  ), shuoxie );
     

     GtkWidget *d123_button = gtk_button_new_from_icon_name ("zoom-original-symbolic",
                                                        GTK_ICON_SIZE_BUTTON);
    gtk_action_bar_pack_start ( GTK_CONTAINER (hand_bts),d123_button);     
     g_signal_connect ( d123_button, "clicked", G_CALLBACK (shuoxie_number_callback  ), shuoxie );
      
     //设置
     GtkWidget *set_bt;
     //set_bt=GTK_WIDGET(gtk_builder_get_object(builder,"bt_set"));
     set_bt=gtk_button_new_from_icon_name ("view-more-symbolic",
                                                         GTK_ICON_SIZE_BUTTON);
     gtk_action_bar_pack_end(GTK_CONTAINER(hand_bts),set_bt);
     g_signal_connect(set_bt,"clicked",G_CALLBACK(set_callback),shuoxie);

    //自动记录
    GtkWidget *shjl_bt;
     shjl_bt=gtk_toggle_button_new_with_label("记录");//gtk_check_button_new_with_label("记录");
    if(shuoxie->autoaddword>0)
        gtk_toggle_button_set_active((shjl_bt),TRUE);
    else
        gtk_toggle_button_set_active((shjl_bt),FALSE);
    g_signal_connect(shjl_bt,"clicked",G_CALLBACK(check_button_callback),shuoxie);
    gtk_action_bar_pack_end(GTK_CONTAINER(hand_bts),shjl_bt);
    //添加
    GtkWidget *xzrk_bt;
    xzrk_bt=gtk_button_new_from_icon_name ("list-add-symbolic",
                                                        GTK_ICON_SIZE_BUTTON);
    gtk_action_bar_pack_end(GTK_CONTAINER(hand_bts),xzrk_bt);
    g_signal_connect(xzrk_bt,"clicked",G_CALLBACK(intext_callback),shuoxie);



    //底部停靠
    GtkWidget *dbtk_bt;
    //dbtk_bt=GTK_WIDGET(gtk_builder_get_object(builder,"bt_dbtk"));
    dbtk_bt=gtk_button_new_from_icon_name ("go-bottom-symbolic",
                                                        GTK_ICON_SIZE_BUTTON);
    gtk_action_bar_pack_end(GTK_CONTAINER(hand_bts),dbtk_bt);
    g_signal_connect(dbtk_bt,"clicked",G_CALLBACK(check_bottom_callback),shuoxie);

}
static GtkWidget *
create_window_ui()
{
    GtkWidget *fixed;
    GtkWidget *drawing;
	ShuoXie *shuoxie;
	GtkWidget *vbox;

	shuoxie = g_new0 ( ShuoXie,1 );
	if ( !create_dbus ( shuoxie ) )							/* 创建D-BUS */
	{
		fprintf ( stderr, "create dbus error. \n" );
		return NULL;
	}	
    shuoxie->autoaddword=get_autoaddword();
    shuoxie->xfup=0;
    shuoxie->autobottom=0;
    if(shuoxie->opacity<0.3)
        shuoxie->opacity=0.3;
    else if(shuoxie->opacity>1)
        shuoxie->opacity=1;
    get_bjcolor(&shuoxie->bj_color);
    get_hbcolor(&shuoxie->hb_color);
    iat_login(NULL,NULL);
    
	char uifile[256];
    sprintf(uifile,"%s/default.glade",getThemeDir());
	GtkBuilder *builder=gtk_builder_new(); 
	if(!gtk_builder_add_from_file(builder, uifile, NULL)){  
                printf("cannot load UI file!\n"); 
                
            }
	
	//shuoxie->window = GTK_WIDGET(gtk_builder_get_object (builder, "main_window"));  
	//if(shuoxie->window==NULL)
        shuoxie->window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
    

    
    gtk_window_set_default_size(GTK_WINDOW(shuoxie->window),490,245);
    // 设置窗口的标题  
    //gtk_window_set_title(GTK_WINDOW(shuoxie->window), "说和写小工具"); 
    //取消关闭按钮
    gtk_window_set_deletable(GTK_WINDOW (shuoxie->window), FALSE);
    //取消最大化按钮
    gtk_window_set_resizable(GTK_WINDOW (shuoxie->window), FALSE);
    
	gtk_window_set_keep_above ( GTK_WINDOW ( shuoxie->window ), TRUE );//窗口置顶
	gtk_window_set_accept_focus ( GTK_WINDOW ( shuoxie->window ), FALSE );
	gtk_window_set_skip_taskbar_hint ( GTK_WINDOW ( shuoxie->window ), TRUE );//任务栏中隐藏
	gtk_window_set_decorated ( GTK_WINDOW ( shuoxie->window ), FALSE );//去掉边框和标题栏显示
    gtk_window_set_opacity(GTK_WINDOW(shuoxie->window), shuoxie->opacity); // 设置透明度函数    
	gtk_window_set_position ( GTK_WINDOW ( shuoxie->window ), GTK_WIN_POS_CENTER );
	
    g_signal_connect (shuoxie->window, "destroy", G_CALLBACK (shuoxie_close_callback), shuoxie); 
    
    


    vbox=gtk_vbox_new(FALSE,3);    
    gtk_container_add(GTK_CONTAINER(shuoxie->window),vbox);

    //系统按钮
	//gtk_widget_set_size_request (ebox, w, h); 
    GtkWidget *header_bar;
    header_bar=gtk_action_bar_new();
    create_headbar(header_bar,builder,shuoxie);      
    GtkWidget *mbox;
	mbox =gtk_event_box_new();//将响应事件的构件加入到事件盒构件
    gtk_container_add(GTK_CONTAINER(mbox),header_bar);
    gtk_widget_set_events ( mbox, gtk_widget_get_events ( mbox )
	                        | GDK_LEAVE_NOTIFY_MASK
	                        | GDK_BUTTON_PRESS_MASK
	                        | GDK_BUTTON_RELEASE_MASK
	                        | GDK_POINTER_MOTION_MASK
	                        | GDK_POINTER_MOTION_HINT_MASK
				| GDK_ENTER_NOTIFY_MASK
				| GDK_LEAVE_NOTIFY_MASK 
                );
    g_signal_connect ( mbox, "button_press_event",
	                   G_CALLBACK ( window_move_callback ), shuoxie );
    gtk_box_pack_start(vbox,mbox,FALSE,FALSE,0);

    //中间
    GtkWidget *hbox=gtk_hbox_new(FALSE,2);
    gtk_box_pack_start(vbox,hbox,FALSE,FALSE,3);


    GtkWidget *zistr;    
    zistr=gtk_grid_new();
    gtk_widget_set_size_request(zistr,180,180);
    gtk_box_pack_start(hbox,zistr,TRUE,FALSE,10);

     
     //侯选字
    for(int i=0;i<HAND_BUTTON_NUM;i++)
    {
        
        shuoxie->hand_button[i]=gtk_button_new_with_label(NULL);
        //gtk_container_add ( GTK_CONTAINER (zistr), shuoxie->hand_button[i] );
        gtk_grid_attach(zistr, shuoxie->hand_button[i], i%4, i/4, 1, 1);
        gtk_widget_set_size_request(shuoxie->hand_button[i],50,50);
        g_signal_connect ( shuoxie->hand_button[i], "clicked", G_CALLBACK ( send_word_callback ), shuoxie );
    }
    
    //画板	
    fixed=gtk_frame_new(NULL);    
    gtk_widget_set_size_request(fixed, 276, 200);
    drawing = create_handwriter_canvas ( shuoxie ,276,200);
	gtk_container_add ( GTK_CONTAINER (fixed), drawing );
    gtk_box_pack_start(hbox,fixed,TRUE,FALSE,10);
	gtk_widget_show ( drawing );
    shuoxie->hand_fixed=drawing;

    //功能按钮    
    GtkWidget *hand_bts;
    hand_bts=gtk_action_bar_new();
    create_handbt_bar(hand_bts,builder,shuoxie);
    gtk_box_pack_start (GTK_CONTAINER (vbox), hand_bts,FALSE,FALSE,0); 
    



    g_object_unref(G_OBJECT(builder)); 
    gtk_widget_show_all(vbox);
    gtk_widget_show_all ( shuoxie->window );
    setDBUSService(shuoxie->service);//传送ＤＢＵＳ数据到ＩＡＴ中
    
    
	return shuoxie->window;
}
int main ( int argc, char **argv )
{
	GtkWidget *window = NULL;
    int res = -1;  
    //初始化信号量，其初值为0  
    res = sem_init(&iat_sem, 0, 0);  
    if(res == -1)  
    {  
        perror("semaphore intitialization failed\n");  
        exit(EXIT_FAILURE);  
    }  
    /*初始化整个GTK+程序，是每一个GTK+程序必不可少的部分*/
	gtk_init ( &argc, &argv );

	window = create_window_ui ();
	if ( !window )
		return 1;

	gtk_main ();
    //清理信号量  
    sem_destroy(&iat_sem);  
    
	return 0;
}

